//
//  SkillRes.m
//  CandyJump
//
//  Created by Bon Lam on 03/07/2011.
//  Copyright 2011 Peru Republic. All rights reserved.
//

#import "SkillRes.h"

#import "Skill.h"
#import "Skill+ProtectedMethods.h"

#import "PRFile.h"

//---------------------------------------------------------------------------------------------------------------------
#define SKILL_RES_FILE_LIST							@"StaticData/GameData/SkillRes.xml"

#define SKILL_RES_XML_ELEM_TAG_SKILL				@"skill"
#define SKILL_RES_XML_ELEM_TAG_BUFF					@"buff"

#define SKILL_RES_XML_ATTR_TAG_CLASS				@"class"
#define SKILL_RES_XML_ATTR_TAG_CODE					@"code"
#define SKILL_RES_XML_ATTR_TAG_TYPE					@"type"
#define SKILL_RES_XML_ATTR_TAG_DISPLAY_NAME			@"displayName"
#define SKILL_RES_XML_ATTR_TAG_ICON					@"icon"

//=====================================================================================================================
@implementation SkillRes

@synthesize skillListDictionary;

static SkillRes *sharedRes = nil;

#pragma mark SkillRes - Singleton
//---------------------------------------------------------------------------------------------------------------------
- (id)init
{
	self = [super init];
	if (self == nil)  {return self;}
	
	return self;
}

//---------------------------------------------------------------------------------------------------------------------
- (void)dealloc
{
	[skillListDictionary release]; skillListDictionary = nil;
	
	[super dealloc];
}

//---------------------------------------------------------------------------------------------------------------------
+ (id)allocWithZone:(NSZone *)zone
{
    return [[self sharedRes] retain];
}

//---------------------------------------------------------------------------------------------------------------------
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

//---------------------------------------------------------------------------------------------------------------------
- (id)retain 
{
    return self;
}

//---------------------------------------------------------------------------------------------------------------------
- (NSUInteger)retainCount
{
    return NSUIntegerMax;  //denotes an object that cannot be released
}

//---------------------------------------------------------------------------------------------------------------------
- (void)release
{
    //do nothing
}

//---------------------------------------------------------------------------------------------------------------------
- (id)autorelease
{
    return self;
}

//---------------------------------------------------------------------------------------------------------------------
+ (SkillRes *)sharedRes
{
    if (sharedRes == nil) {
        sharedRes = [[super allocWithZone:NULL] init];
    }
    return sharedRes;
}

#pragma mark SkillRes - Load Data
//---------------------------------------------------------------------------------------------------------------------
- (void)loadSkills
{
	if (skillListDictionary != nil) {
		[skillListDictionary release];
		skillListDictionary = nil;
	}
	skillListDictionary = [[NSMutableDictionary alloc] init];
	
	NSString* filePath = [PRFile getFilePath:SKILL_RES_FILE_LIST];
	[self parseXMLFile:filePath];
}

#pragma mark SkillRes - NSXMLParserDelegate
//---------------------------------------------------------------------------------------------------------------------
- (BOOL)parseXMLFile:(NSString *)filename
{
	//  Load Skill List XML file
	NSData *xmlData = [NSData dataWithContentsOfFile:filename];
	if (xmlData == nil)  {
		NSLog(@"[SkillRes parseXMLFile:filename] Error - Unable to parse file: ""%@""", filename);
		return NO;
	}
	
	NSError* error = nil;
	[self parseXMLData:xmlData parseError:&error];
	
	return (error == nil);
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parseXMLData:(NSData *)data parseError:(NSError **)error
{
	NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
	
    NSError *parseError = [parser parserError];
    if (parseError && error)  {
        *error = parseError;
    }
    [parser release];
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
	if ([elementName isEqualToString:SKILL_RES_XML_ELEM_TAG_SKILL])
	{
		NSString* className = [attributeDict valueForKey:SKILL_RES_XML_ATTR_TAG_CLASS];
		Class skillClass = NSClassFromString(className);
		if(skillClass == nil) { 
			NSLog(@"[SkillRes parser: didStartElement: namespaceURI: qualifiedName: attributes:] Error - Unable to find class: ""%@"" ", className);
			return;
		}
		
		NSString* skillCode = [attributeDict valueForKey:SKILL_RES_XML_ATTR_TAG_CODE];
		if(skillCode == nil) {
			NSLog(@"[SkillRes parser: didStartElement: namespaceURI: qualifiedName: attributes:] Error - Unable to read skill code");
			return;
		}
		
		NSString* skillTypeStr = [attributeDict valueForKey:SKILL_RES_XML_ATTR_TAG_TYPE];
		if(skillTypeStr == nil) {
			NSLog(@"[SkillRes parser: didStartElement: namespaceURI: qualifiedName: attributes:] Error - Unable to read skill type");
			return;
		}
		
		NSString* displayName = [attributeDict valueForKey:SKILL_RES_XML_ATTR_TAG_DISPLAY_NAME];
		if(displayName == nil) {
			NSLog(@"[SkillRes parser: didStartElement: namespaceURI: qualifiedName: attributes:] Error - Unable to read skill displayName");
			return;
		}
		
		NSString* iconFile = [attributeDict valueForKey:SKILL_RES_XML_ATTR_TAG_ICON];
		if(iconFile == nil) {
			NSLog(@"[SkillRes parser: didStartElement: namespaceURI: qualifiedName: attributes:] Error - Unable to read skill icon");
			return;
		}
		
		currentReadingSkill = [[skillClass alloc] init];
		currentReadingSkill.skillCode = skillCode;
		currentReadingSkill.skillType = [Skill skillTypeByString:skillTypeStr];
		currentReadingSkill.displayName = displayName;
		[skillListDictionary setObject:currentReadingSkill forKey:skillCode];
		
		return;
	}
	
	if ([elementName isEqualToString:SKILL_RES_XML_ELEM_TAG_BUFF])
	{
		NSString* buffCode = [attributeDict valueForKey:SKILL_RES_XML_ATTR_TAG_CODE];
		[currentReadingSkill.buffCodeArray addObject:buffCode];
		
		return;
	}
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
	if ([elementName isEqualToString:SKILL_RES_XML_ELEM_TAG_SKILL])
	{
		if (currentReadingSkill != nil)
		{	
			[currentReadingSkill release];
			currentReadingSkill = nil;
		}
	}
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
	
}

//---------------------------------------------------------------------------------------------------------------------
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
	
}


@end